package spring.cloud.tasks.tasks_manager.tasks_manager.task_item_allot.executor;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.tasks_manager.tasks_manager.service.AllotTaskItemService;
import spring.cloud.tasks.tasks_manager.tasks_manager.task_item_allot.TaskItemAllotTask;
import spring.cloud.tasks.tasks_manager.tasks_manager.task_item_allot.TasksFullTaskItemTask;
import spring.cloud.tasks.tasks_manager.tasks_manager.task_item_allot.task.TaskItem;

import java.util.ArrayList;
import java.util.List;

/**
 * executor上线，仅仅添加executor空壳，如果其不存在；如果已经存在，重新设置下ip，防止ExecuteJobServerOnlineShardingTask先于执行而没设ip
 * <p>
 * 特别的，如果当前没有executor，也就是这是第一台executor上线，则需要域全量分片，因为可能已经有作业处于启用状态了。
 */
@Slf4j
@Setter
@Getter
public class ExecutorOnlineTaskItemAllotTask extends TaskItemAllotTask {

    private String executorId;

    private String ip;

    public ExecutorOnlineTaskItemAllotTask(AllotTaskItemService allotTaskItemService, String executorId, String ip) {
        super(allotTaskItemService);
        this.allotTaskItemService = allotTaskItemService;
        this.executorId = executorId;
        this.ip = ip;
    }

    @Override
    protected void logStartInfo() {
        log.info("Execute the {} with {} online", this.getClass().getSimpleName(), executorId);
    }

    @Override
    protected boolean pick(List<String> taskIdList,//
                           List<String> enableTaskIdList,//
                           List<TaskItem> taskItemList,//
                           List<Executor> onlineExecutorList,//
                           List<Executor> onlineOwnTrafficExecutorList) throws Exception {
        // 如果没有Executor在运行，则需要进行全量分片
        if (onlineExecutorList.isEmpty()) {
            log.warn("There are no running executors, need all sharding");
            allotTaskItemService.setNeedAllSharding(true);
            allotTaskItemService.shardingCountIncrementAndGet();
            executorService.submit(new TasksFullTaskItemTask(allotTaskItemService));
            return false;
        }

        Executor targetExecutor = null;
        for (int i = 0; i < onlineExecutorList.size(); i++) {
            Executor executor = onlineExecutorList.get(i);
            if (executor.getExecutorId().equals(executorId)) {
                targetExecutor = executor;
                break;
            }
        }
        if (targetExecutor == null) {
            targetExecutor = new Executor();
            targetExecutor.setExecutorId(executorId);
            targetExecutor.setIp(ip);
            targetExecutor.setLostTraffic(getExecutorLostTraffic(executorId));
            targetExecutor.setTaskIdList(new ArrayList<String>());
            targetExecutor.setTaskItemList(new ArrayList<TaskItem>());
            onlineExecutorList.add(targetExecutor);
            if (!targetExecutor.isLostTraffic()) {
                onlineOwnTrafficExecutorList.add(targetExecutor);
            }
        } else { // 重新设置下ip
            targetExecutor.setIp(ip);
        }

        return true;
    }

}
